function varargout = Forward(varargin)
gui_Singleton = 1;
gui_State = struct('gui_Name',       mfilename, ...
                   'gui_Singleton',  gui_Singleton, ...
                   'gui_OpeningFcn', @Forward_OpeningFcn, ...
                   'gui_OutputFcn',  @Forward_OutputFcn, ...
                   'gui_LayoutFcn',  [] , ...
                   'gui_Callback',   []);
if nargin && ischar(varargin{1})
    gui_State.gui_Callback = str2func(varargin{1});
end

if nargout
    [varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:});
else
    gui_mainfcn(gui_State, varargin{:});
end



% --- Executes just before Forward is made visible.
function Forward_OpeningFcn(hObject, eventdata, handles, varargin)
    movegui('center')
handles.output = hObject;
guidata(hObject, handles);
initialize_gui(hObject, handles, false);



% --- Outputs from this function are returned to the command line.
function varargout = Forward_OutputFcn(hObject, eventdata, handles) 
varargout{1} = handles.output;



function latitude1_Callback(hObject, eventdata, handles)
format long
   lat_str=get(hObject, 'String');
   di=strfind(lat_str,'*');
   if isempty(di)
       handles.lat.tag=0;
    latitude1 = str2double(get(hObject, 'String'));
    handles.lat.du=fix(latitude1);
    handles.lat.fen=fix((latitude1-handles.lat.du)*60);
    handles.lat.miao=roundn(((latitude1-handles.lat.du)*60-handles.lat.fen)*60,-2);
   else
       handles.lat.tag=1;
       fi=strfind(lat_str,'''');
       mi=strfind(lat_str,'"');
       du=str2double(lat_str(1:di-1));
       if ~isempty(fi)
           fen=str2double(lat_str(di+1:fi-1));
       else
           fen=0;
       end
       if ~isempty(mi)&&~isempty(fi)
           miao=str2double(lat_str(fi+1:mi-1));
       elseif ~isempty(mi)
           miao=str2double(lat_str(di+1:mi-1));
       else
           miao=0;
       end
       latitude1=du+fen/60+miao/3600;
       handles.s.lat=latitude1;
   end
    latitude1=roundn(latitude1,-6);
handles.pos.lat1=latitude1;
guidata(hObject,handles)


% --- Executes during object creation, after setting all properties.
function latitude1_CreateFcn(hObject, eventdata, handles)
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end



function longitude1_Callback(hObject, eventdata, handles)
format long
   lon_str=get(hObject, 'String');
   di=strfind(lon_str,'*');
   if isempty(di)
       handles.lon.tag=0;
    longitude1 = str2double(get(hObject, 'String'));
    handles.lon.du=fix(longitude1);
    handles.lon.fen=fix((longitude1-handles.lon.du)*60);
    handles.lon.miao=roundn(((longitude1-handles.lon.du)*60-handles.lon.fen)*60,-2);
   else
       handles.lon.tag=1;
       fi=strfind(lon_str,'''');
       mi=strfind(lon_str,'"');
       du=str2double(lon_str(1:di-1));
       if ~isempty(fi)
           fen=str2double(lon_str(di+1:fi-1));
       else
           fen=0;
       end
       if ~isempty(mi)&&~isempty(fi)
           miao=str2double(lon_str(fi+1:mi-1));
       elseif ~isempty(mi)
           miao=str2double(lon_str(di+1:mi-1));
       else
           miao=0;
       end
       longitude1=du+fen/60+miao/3600;
       handles.s.lon=longitude1;
   end
    longitude1=roundn(longitude1,-6);
handles.pos.lon1=longitude1;
guidata(hObject,handles)



% --- Executes during object creation, after setting all properties.
function longitude1_CreateFcn(hObject, eventdata, handles)
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end



function latitude2_Callback(hObject, eventdata, handles)
format long
   lat_str=get(hObject, 'String');
   di=strfind(lat_str,'*');
   if isempty(di)
    latitude2 = str2double(get(hObject, 'String'));
   else
       fi=strfind(lat_str,'''');
       mi=strfind(lat_str,'"');
       du=str2double(lat_str(1:di-1));
       if ~isempty(fi)
           fen=str2double(lat_str(di+1:fi-1));
       else
           fen=0;
       end
       if ~isempty(mi)&&~isempty(fi)
           miao=str2double(lat_str(fi+1:mi-1));
       elseif ~isempty(mi)
           miao=str2double(lat_str(di+1:mi-1));
       else
           miao=0;
       end
       latitude2=du+fen/60+miao/3600;
   end
    latitude2=roundn(latitude2,-6);
handles.pos.lat2=latitude2;
guidata(hObject,handles)

% --- Executes during object creation, after setting all properties.
function latitude2_CreateFcn(hObject, eventdata, handles)
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end



function longitude2_Callback(hObject, eventdata, handles)
format long
   lon_str=get(hObject, 'String');
   di=strfind(lon_str,'*');
   if isempty(di)
    longitude2 = str2double(get(hObject, 'String'));
   else
       fi=strfind(lon_str,'''');
       mi=strfind(lon_str,'"');
       du=str2double(lon_str(1:di-1));
       if ~isempty(fi)
           fen=str2double(lon_str(di+1:fi-1));
       else
           fen=0;
       end
       if ~isempty(mi)&&~isempty(fi)
           miao=str2double(lon_str(fi+1:mi-1));
       elseif ~isempty(mi)
           miao=str2double(lon_str(di+1:mi-1));
       else
           miao=0;
       end
       longitude2=du+fen/60+miao/3600;
   end
    longitude2=roundn(longitude2,-6);
handles.pos.lon2=longitude2;
guidata(hObject,handles)

% --- Executes during object creation, after setting all properties.
function longitude2_CreateFcn(hObject, eventdata, handles)
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end


% --- Executes on button press in calculate.
function calculate_Callback(hObject, eventdata, handles)

[pos_x,pos_y]=WP_Pos2XY(handles.pos.lon1,handles.pos.lat1,handles.pos.lon2,handles.pos.lat2);
handles.s.psi=WP_Psi(pos_x,pos_y);
handles.s.dis=sqrt(pos_x^2+pos_y^2);

if handles.lat.tag==0
    handles.s.lat=strcat(num2str(handles.lat.du),'*  ',num2str(handles.lat.fen),'''  ',num2str(handles.lat.miao),'"');
end
if handles.lon.tag==0
    handles.s.lon=strcat(num2str(handles.lon.du),'*  ',num2str(handles.lon.fen),'''  ',num2str(handles.lon.miao),'"');
end
set(handles.s_lon,'String',handles.s.lon);
set(handles.s_lat,'String',handles.s.lat);
set(handles.s_psi,'String',handles.s.psi);
set(handles.s_dis,'String',handles.s.dis);


% --- Executes on button press in reset.
function reset_Callback(hObject, eventdata, handles)
initialize_gui(gcbf, handles, true);


% --------------------------------------------------------------------
function initialize_gui(fig_handle, handles, isreset)
% If the metricdata field is present and the reset flag is false, it means
% we are we are just re-initializing a GUI by calling it from the cmd line
% while it is up. So, bail out as we dont want to reset the data.
if isfield(handles, 'pos') && ~isreset
    return;
end

handles.pos.lon1 = 0;
handles.pos.lat1 = 0;
handles.pos.lon2 = 0;
handles.pos.lat2 = 0;

handles.s.lon = 0;
handles.s.lat = 0;
handles.s.psi = 0;
handles.s.dis = 0;

set(handles.longitude1, 'String',handles.pos.lon1);
set(handles.latitude1, 'String',handles.pos.lat1);
set(handles.longitude2, 'String',handles.pos.lon2);
set(handles.latitude2, 'String',handles.pos.lat2);

set(handles.s_lon, 'String',handles.s.lon);
set(handles.s_lat, 'String',handles.s.lat);
set(handles.s_psi, 'String',handles.s.psi);
set(handles.s_dis, 'String',handles.s.dis);

guidata(handles.figure1, handles);


% --------------------------------------------------------------------
function [x,y]=WP_BL2xy(B,L)
    Rad2Deg=180/pi;
    a=6378137; e2 =0.0066943799013;e22=0.00673949674227;
	L0 =floor(L)/Rad2Deg; 
    B =B/Rad2Deg;   L =L/Rad2Deg;
	sinB =sin(B);
	cosB =cos(B); cos3B=cosB^3; cos5B =cosB^5;
	l1  =(L-L0); l2=l1*l1; l3=l2*l1; l4=l3*l1; l5=l4*l1; l6=l5*l1;

	t =tan(B); n2=e22*cosB*cosB; t2=t*t; t4=t2*t2;  n4=n2*n2;
	N = a/sqrt(1-e2*sinB*sinB);

	m0 =a*(1-e2);
	m2 =3*e2*m0/2.0;
	m4 =5*e2*m2/4.0;
	m6 =7*e2*m4/6.0;
	m8 =9*e2*m6/8.0;

	a0 =  m0    +   m2/2.0  + 3*m4/8.0  + 5*m6/16.0 + 35*m8/128.0;
	a2 =m2/2.0  +   m4/2.0  +15*m6/32.0 + 7*m8/16.0;
	a4 =m4/8.0  + 3*m6/16.0 + 7*m8/32.0;
	a6 =m6/32.0 +   m8/16.0;
	a8 =m8/128.0;

	X1 = a0*B - a2*sin(2*B)/2.0 + a4*sin(4*B)/4.0 - a6*sin(6*B)/6.0 + a8*sin(8*B)/8.0;

	x =X1 +N*sinB*cosB*l2/2 + N*sinB*cos3B*(5-t2+9*n2+4*n4)*l4/24 ... 
		  +N*sinB*cos5B*(61-58*t2+t4)*l6/720;
	y =N*cosB*l1 + N*cos3B*(11-t2+n2)*l3/6 + N*cos5B*(5-18*t2+t4+14*n2-58*n2*t2)*l5/120;
	y =y +500000;
    
    
 function [x,y]=WP_Pos2XY ( lon_ref,lat_ref,lon,lat)    
  [x_des,y_des]=WP_BL2xy(lat,lon);
  [x_ref,y_ref]=WP_BL2xy(lat_ref, lon_ref);
	y =x_des - x_ref; 
	x =y_des - y_ref; 
    
    
    
function  psi=WP_Psi(x,y)
 
    Rad2Deg=180/pi;     
    psi = atan2(y,x)*Rad2Deg;
    if ((psi<=180.0) && (psi>90.0))
        psi = 450.0 - psi;
    else
        psi =  90.0 - psi;
    end
    
    if ((abs(x)+abs(y))<1e-6) 
    psi=0.0;
    end

        
